﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;


namespace FallingSand
{
    public class Grid
    {
        private Random rand = new Random();
        private bool _checkState = true;

        //the particles
        private List<Particle> _particles = new List<Particle>();

        private Color[] _clrData;
        private Texture2D texture;

        private int WIDTH = 0;
        private int HEIGHT = 0;

        public class Particle
        {
            public Particle()
            {
                CheckState = true;
                Type = 0;
            }
            public int Type { get; set; }
            public bool CheckState { get; set; }
        }
        public Grid(int Width, int Height, GraphicsDevice graphics)
        {
            this.WIDTH = (int)(Width * .25f);
            this.HEIGHT = (int)(Height * .25f);

            for (int x = 0; x < WIDTH; x++)
            {
                for (int y = 0; y < HEIGHT; y++)
                {
                    _particles.Add(new Particle());
                }
                
            }
            texture = new Texture2D(graphics, this.WIDTH, this.HEIGHT);
            _clrData = new Color[_particles.Count];
        }
        public void SpawnSand(Microsoft.Xna.Framework.Rectangle rect, int Type)
        {
            for (int x = rect.Left; x < rect.Right; x++)
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    _particles[_getLocationOnArray(x, y)].Type = Type;
                }   
            }
        }
        public int DeleteSandCount(Microsoft.Xna.Framework.Rectangle rect, int Type)
        {
            int count = 0;
            for (int x = (int)(rect.Left * .25f); x < (int)(rect.Right * .25f); x++)
            {
                for (int y = (int)(rect.Top * .25f); y < (int)(rect.Bottom * .25f); y++)
                {
                    if (_particles[_getLocationOnArray(x, y)].Type == Type)
                    {
                        count++;
                    }
                    _particles[_getLocationOnArray(x, y)].Type = 0;
                }
            }
            return count;

        }
        public void DrawTextureData( SpriteBatch spritebatch)
        {
           
      
            for (int i = 0; i < _particles.Count; i++)
			{
                if (_particles[i].Type == 1)
                {
                    _clrData[i] = new Color(255, 204, 0, 255);
                }
                else if (_particles[i].Type == 2)
                {
                    _clrData[i] = new Color(50, 50, 50, 255);
                }
                else
                {
                    _clrData[i] = new Color(255, 255, 255, 255);
                }
			}
            texture.GraphicsDevice.Textures[0] = null;
            texture.SetData(_clrData);
            spritebatch.Draw(texture, Vector2.Zero,null, Color.White,0.0f,Vector2.Zero,4.0f,SpriteEffects.None,0);
        }
        private int _getLocationOnArray(int x, int y)
        {
            if (x < WIDTH && x > 0)
            {
                if (y < HEIGHT && y > 0)
                {
                    return ((y * WIDTH) + x);
                }
            }
            return ((HEIGHT * WIDTH)-1 );
        }
        public void ImageToDataArray(Texture2D texture)
        {
            Color[] clr = new Color[texture.Width * texture.Height];
            texture.GetData(clr);
            for (int x = ((WIDTH / 2) - (texture.Width / 2)); x < (WIDTH / 2) + (texture.Width / 2); x++)
            {
                for (int y = (HEIGHT/2)-(texture.Height/2); y <(HEIGHT/2)+(texture.Height/2); y++)
                {
                    int XClrData = x - ((WIDTH / 2) - (texture.Width / 2));
                    int YClrData = y - ((HEIGHT / 2) - (texture.Height / 2));
                    if (clr[(YClrData * texture.Width) + XClrData] == Color.Black)
                    {
                        _particles[_getLocationOnArray(x, y)].Type = 2;
                    }
                }     
            }
        }
        public void update()
        {
            if (_checkState)
                _checkState = false;
            else
                _checkState = true;
             int NewLocation= 0;

            for (int x = 0; x < WIDTH; x++)
            {
                for (int y = 0; y < HEIGHT; y++)
                {
                    int MyParticle =  _getLocationOnArray(x,y);
                    if (_particles[MyParticle].CheckState != _checkState)
                    {
                        _particles[MyParticle].CheckState = _checkState;

                        if (_particles[MyParticle].Type == 1)
                        {
                            NewLocation = _getLocationOnArray(x , y + 1);
                            if (_particles[NewLocation].Type == 0)
                            {
                                _particles[MyParticle].Type = 0;
                                _particles[NewLocation].Type = 1;
                                _particles[NewLocation].CheckState = _checkState;
                            }
                            else  if (rand.Next(0, 100) < 50)
                            {
                                 NewLocation = _getLocationOnArray(x+1, y+1);
                                if (_particles[NewLocation].Type == 0)
                                {
                                    _particles[MyParticle].Type = 0;
                                    _particles[NewLocation].Type = 1;
                                    _particles[NewLocation].CheckState = _checkState;
                                }
                                else
                                {
                                    NewLocation = _getLocationOnArray(x+1,y);
                                    if (_particles[NewLocation].Type == 0)
                                    {
                                        _particles[MyParticle].Type = 0;
                                        _particles[NewLocation].Type = 1;
                                        _particles[NewLocation].CheckState = _checkState;
                                    }
                                }
                            }
                            else 
                            {
                                 NewLocation = _getLocationOnArray(x-1, y+1);
                                if (_particles[NewLocation].Type == 0)
                                {
                                    _particles[MyParticle].Type = 0;
                                    _particles[NewLocation].Type = 1;
                                    _particles[NewLocation].CheckState = _checkState;
                                }
                                else
                                {
                                    NewLocation = _getLocationOnArray(x -1, y);
                                    if (_particles[NewLocation].Type == 0)
                                    {
                                        _particles[MyParticle].Type = 0;
                                        _particles[NewLocation].Type = 1;
                                        _particles[NewLocation].CheckState = _checkState;
                                    }
                                }
                            }
    

                        }
                        else
                        {
                            _particles[MyParticle].CheckState = _checkState;
                        }

                    }
                }
            }
        }
    }
}
